package com.xwj.nio.guava;

import com.google.common.util.concurrent.*;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Guava非阻塞异步回调
 *
 * @author xwj
 * @date 2020/6/11
 */
public class GuavaFutureDemo {
    /**
     * 烧开水线程
     */
    private static class HotWaterJob implements Callable<Boolean> {
        @Override
        public Boolean call() throws Exception {
            try {
                System.out.println("洗好水壶");
                System.out.println("灌上凉水");
                System.out.println("放在火上");
                //线程睡眠一段时间，代表烧水中
                TimeUnit.SECONDS.sleep(2);
                System.out.println("水开了");
            } catch (InterruptedException e) {
                System.out.println("发生异常被中断");
                return false;
            }
            System.out.println("烧水工作，运行结束");
            return true;
        }
    }

    /**
     * 清洗线程
     */
    private static class WashJob implements Callable<Boolean> {
        @Override
        public Boolean call() throws Exception {
            try {
                System.out.println("洗茶壶");
                System.out.println("洗茶杯");
                System.out.println("拿茶叶");
                //线程睡眠一段时间，代表清洗中
                TimeUnit.SECONDS.sleep(2);
                System.out.println("洗完了");
            } catch (InterruptedException e) {
                System.out.println("清洗工作发生异常被中断");
                return false;
            }
            System.out.println("清洗工作运行结束");
            return true;
        }
    }

    /**
     * 泡茶线程
     */
    private static class MakeTeaJob implements Runnable {

        volatile boolean hotWater = false;
        volatile boolean wash = false;

        @Override
        public void run() {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println("等待烧水和清洗杯子中......");
                } catch (InterruptedException e) {
                    System.out.println(Thread.currentThread().getName() + "发生异常被中断.");
                }
                if (hotWater && wash) {
                    System.out.println("等待结束，泡茶喝");
                } else if (!hotWater) {
                    System.out.println("水烧挂掉了");
                } else if (!wash) {
                    System.out.println("洗杯子挂掉了");
                }
            }
        }
    }

    public static void main(String[] args) {
        MakeTeaJob makeTeaJob = new MakeTeaJob();
        new Thread(makeTeaJob).start();

        // 创建java 线程池
        ExecutorService jPool = Executors.newFixedThreadPool(10);
        // 包装java线程池，构造guava 线程池
        ListeningExecutorService gPool = MoreExecutors.listeningDecorator(jPool);

        // 烧水
        Callable<Boolean> hotWaterJob = new HotWaterJob();
        // 提交烧水的业务逻辑，取到异步任务
        ListenableFuture<Boolean> hotWaterFuture = gPool.submit(hotWaterJob);
        // 绑定任务执行完成后的回调，到异步任务
        Futures.addCallback(hotWaterFuture, new FutureCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean r) {
                if (r) {
                    makeTeaJob.hotWater = true;
                }
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println("烧水失败，没有茶喝了");
            }
        });

        // 清洗
        Callable<Boolean> washJob = new WashJob();
        // 提交清洗的业务逻辑，取到异步任务
        ListenableFuture<Boolean> washFuture = gPool.submit(washJob);
        //绑定任务执行完成后的回调，到异步任务
        Futures.addCallback(washFuture, new FutureCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean r) {
                if (r) {
                    makeTeaJob.wash = true;
                }
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println("杯子洗不了，没有茶喝了");
            }
        });
    }
}
